package com.agent.action.client;

import com.agent.action.entity.AgentMessageHistoryEntity;
import com.agent.action.entity.ConversationNameEntity;
import com.agent.action.entity.DifyAgentEntity;
import com.agent.action.entity.PauseEntity;
import com.agent.action.interfaces.AgentClient;
import com.agent.action.interfaces.BuilderInterface;
import com.agent.action.param.ConversationNameParam;
import com.agent.action.param.PauseParam;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;

/**
 * 智能体交互
 * @param <T>
 */
@Data
@Slf4j
public class DifyAgentClient<T> implements AgentClient<T>, BuilderInterface<DifyAgentClient<T>> {
    /**
     * Dify智能体Uri
     */
    private String uri;
    /**
     * Dify智能体调用具体Url
     */
    private String url;
    /**
     * Dify智能体Key
     */
    private String key;
    /**
     * WebClient
     */
    private WebClient webClient;


    /**
     * 设置请求uri
     * @param url
     * @return
     */
    @Override
    public DifyAgentClient<T> url(String url){
        this.url = url;
        return this;
    }

    /**
     * 设置key
     * @param key
     * @return
     */
    @Override
    public DifyAgentClient<T> key(String key){
        this.key = key;
        return this;
    }

    /**
     * 构建客户端
     * @param uri
     * @return
     */
    @Override
    public DifyAgentClient<T> builder(String uri){
        this.webClient=WebClient.builder()
                .baseUrl(uri)
                .defaultHeader("Content-Type","application/json")
                .defaultHeader("Authorization","Bearer "+key)
                .build();
        return this;
    }

    /**
     * 普通对话
     * @param difyAgentEntity
     * @return
     */
    @Override
    public Flux<String> chat(DifyAgentEntity<T> difyAgentEntity) {
        String strDify = JSON.toJSONString(difyAgentEntity);
        log.error("DifyAgentEntity:{}", strDify);
        return webClient.post()
                .uri("/"+url)
                .bodyValue(strDify)
                .retrieve()
                .bodyToFlux(String.class);
    }

    /**
     * 获取会话历史消息
     * @param message
     * @return
     */
    @Override
    public JSONObject getMessageHistory(AgentMessageHistoryEntity message) {
        return JSONObject.parseObject(webClient.get()
                .uri(uriBuilder -> uriBuilder
                        .path("/"+url)
                        .queryParam("conversation_id",message.getConversation_id())
                        .queryParam("user",message.getUser())
                        .queryParam("first_id",message.getFirst_id())
                        .queryParam("limit",message.getLimit())
                        .build())
                .retrieve()
                .bodyToMono(String.class)
                        .block());

    }

    /**
     * 暂停智能体交互
     * @param pauseParam
     */
    @Override
    public void pause(PauseParam pauseParam) {
        log.info("PauseParam:{}", pauseParam);
        PauseEntity pauseEntity = new PauseEntity();
        String taskId=pauseParam.getTaskId();
        pauseEntity.setUser(pauseParam.getUserId());
        webClient.post()
                .uri("/chat-messages/"+taskId+"/stop")
                .bodyValue(JSON.toJSONString(pauseEntity))
                .retrieve()
                .bodyToMono(String.class)
                .subscribe();

    }

    /**
     * 创建会话名称
     * @param param
     * @return
     */
    @Override
    public String makeConversationName(ConversationNameParam param) {
        log.info("ConversationNameParam:{}", param);
        ConversationNameEntity conversationNameEntity = new ConversationNameEntity();
        conversationNameEntity.setUser(param.getUser());
        conversationNameEntity.setAuto_generate(param.isAuto_generate());
        return webClient.post()
                .uri("/conversations/"+param.getConversationId()+"/name")
                .bodyValue(JSON.toJSONString(conversationNameEntity))
                .retrieve()
                .bodyToMono(String.class)
                .block();
    }

}
